<template>
  <picker
    mode="multiSelector"
    :range="addressRange"
    range-key="name"
    @change="pickerChange"
    @columnchange="columnchange"
    :value="value"
    @cancel="$emit('cancel')"
    :disabled="disabled"
  >
    <slot></slot>
  </picker>
</template>

<script>
import address from "../../utils/address.json";
export default {
  /**
   * @param modelValue Array(string) ['四川省', '成都市', '武侯区']
   * @param codeValue Array(string | number) [ "51","5101", "510107" ]
   * @param selectIndex Array(number) [ 0, 0, 0 ]
   * @param disabled 禁用
  */
  props: {
    modelValue: Array,
    codeValue: Array,
    disabled: {
      type: Boolean,
      default: false,
    },
    selectIndex: {
      type: Array,
      default: () => [0, 0, 0],
    },
  },

  emits: [
    "update:modelValue",
    "update:codeValue",
    "columnchange",
    "change",
    "cancel",
  ],
  data() {
    return {
      addressRange: [],
      value: [0, 0, 0],
    };
  },
  created() {
    this.value = [...this.selectIndex];
    this.addressRange[0] = address;
    this.setDefByCode();
    this.setDefByName();
  },
  watch: {
    modelValue() {
      this.setDefByName();
    },
    codeValue() {
      this.setDefByCode();
    },
  },
  methods: {
    columnchange(e) {
      const { column, value } = e.detail;
      this.$emit("columnchange", e.detail);
      if (column === 0) {
        this.addressRange[1] = this.addressRange[0][value].child;
        this.addressRange[2] = this.addressRange[1][this.value[1]]?.child || this.addressRange[1][0].child;
      }
      if (column === 1) {
        this.addressRange[2] = this.addressRange[1][value].child;
      }
    },
    pickerChange(e) {
      const v = e.detail.value;
      const { name: province } = this.addressRange[0][v[0]];
      const { name: city } = this.addressRange[1][v[1]];
      const {
        code: areaCode,
        name: area,
        cityCode,
        provinceCode,
      } = this.addressRange[2][v[2]];
      this.$emit("change", {
        areaCode,
        area,
        cityCode,
        provinceCode,
        province,
        city,
      });
      this.$emit("update:modelValue", [province, city, area]);
      this.$emit("update:codeValue", [provinceCode, cityCode, areaCode]);
    },
    setDefByCode() {
      if (this.codeValue instanceof Array && this.codeValue.length >= 1) {
        const provinceIndex = this.addressRange[0].findIndex(
          (item) => item.code === this.codeValue[0].toString()
        );
        if (provinceIndex === -1) {
          this.addressRange[1] = this.addressRange[0][0].child;
          this.addressRange[2] = this.addressRange[1][0].child;
          return;
        }
        this.addressRange[1] = this.addressRange[0][provinceIndex].child;

        const cityIndex = this.addressRange[1].findIndex(
          (item) => item.code === this.codeValue[1]?.toString()
        );
        if (cityIndex === -1) {
          this.addressRange[2] = this.addressRange[1][0].child;
          this.$nextTick(() => {
            this.value = [provinceIndex, 0, 0];
          });
          return;
        }
        this.addressRange[2] = this.addressRange[1][cityIndex].child;

        const areaIndex = this.addressRange[2].findIndex(
          (item) => item.code === this.codeValue[2]?.toString()
        );
        if (areaIndex === -1) {
          this.$nextTick(() => {
            this.value = [provinceIndex, cityIndex, 0];
          });
          return;
        }
        this.$nextTick(() => {
          this.value = [provinceIndex, cityIndex, areaIndex];
        });
      } else {
        this.addressRange[1] = this.addressRange[0][0].child;
        this.addressRange[2] = this.addressRange[1][0].child;
      }
    },
    setDefByName() {
      if (this.modelValue instanceof Array && this.modelValue.length >= 1) {
        const provinceIndex = this.addressRange[0].findIndex(
          (item) => item.name === this.modelValue[0]
        );
        if (provinceIndex === -1) {
          this.addressRange[1] = this.addressRange[0][0].child;
          this.addressRange[2] = this.addressRange[1][0].child;
          return;
        }
        this.addressRange[1] = this.addressRange[0][provinceIndex].child;

        const cityIndex = this.addressRange[1].findIndex(
          (item) => item.name === this.modelValue[1]
        );
        if (cityIndex === -1) {
          this.addressRange[2] = this.addressRange[1][0].child;
          this.$nextTick(() => {
            this.value = [provinceIndex, 0, 0];
          });
          return;
        }
        this.addressRange[2] = this.addressRange[1][cityIndex].child;

        const areaIndex = this.addressRange[2].findIndex(
          (item) => item.name === this.modelValue[2]
        );
        if (areaIndex === -1) {
          this.$nextTick(() => {
            this.value = [provinceIndex, cityIndex, 0];
          });
          return;
        }
        this.$nextTick(() => {
          this.value = [provinceIndex, cityIndex, areaIndex];
        });
      } else {
        this.addressRange[1] = this.addressRange[0][0].child;
        this.addressRange[2] = this.addressRange[1][0].child;
      }
    },
  },
};
</script>
